﻿// -------------------------------------------------------------------------
//    @FileName         :    TestNFTimeUtility.h
//    @Author           :    gaoyi
//    @Date             :    2025-01-10
//    @Email            :    445267987@qq.com
//    @Module           :    TestNFTimeUtility
//
// -------------------------------------------------------------------------

/**
 * @file TestNFTimeUtility.h
 * @brief NFTimeUtility时间工具类单元测试
 * 
 * 此文件提供了对NFTimeUtility类的完整单元测试，包括：
 * - 基础时间转换功能测试
 * - 日期时间计算功能测试
 * - 周期性判断功能测试
 * - 时区处理功能测试
 * - 边界条件和异常情况测试
 */

#pragma once

#include <gtest/gtest.h>
#include "NFComm/NFCore/NFTimeUtility.h"
#include "NFComm/NFCore/NFServerTime.h"
#include <ctime>
#include <string>
#include <chrono>

#include "evpp/gettimeofday.h"

/**
 * @brief NFTimeUtility测试类
 * 
 * 继承自Google Test的测试框架，提供测试环境的初始化和清理。
 */
class NFTimeUtilityTest : public ::testing::Test
{
protected:
    /**
     * @brief 测试用例开始前的初始化
     */
    void SetUp() override
    {
        // 设置固定的时间点用于测试
        // 使用2024年1月15日 10:30:45作为基准时间
        m_testTimestamp = 1705321845; // 2024-01-15 10:30:45 UTC

        // 获取当前时间作为测试参考
        m_currentTime = time(nullptr);
    }

    /**
     * @brief 测试用例结束后的清理
     */
    void TearDown() override
    {
        // 清理测试环境
    }

protected:
    time_t m_testTimestamp; ///< 测试用的固定时间戳
    time_t m_currentTime; ///< 当前时间戳
};

// ========== 基础时间转换功能测试 ==========

/**
 * @brief 测试时间格式化为字符串功能
 *
 * 测试SecondToStr、DateTimeToStr等时间格式化函数
 */
TEST_F(NFTimeUtilityTest, TimeFormatTest)
{
    // 测试SecondToStr - 将秒数转换为时:分:秒格式
    {
        std::string result = NFTimeUtility::SecondToStr(3665); // 1小时1分5秒
        EXPECT_EQ(result, "01:01:05");
    }

    {
        std::string result = NFTimeUtility::SecondToStr(0);
        EXPECT_EQ(result, "00:00:00");
    }

    {
        std::string result = NFTimeUtility::SecondToStr(86399); // 23:59:59
        EXPECT_EQ(result, "23:59:59");
    }

    // 测试DateTimeToStr - 时间戳转换为日期时间字符串
    {
        std::string result = NFTimeUtility::DateTimeToStr(m_testTimestamp);
        // 结果应该包含年月日和时分秒信息
        EXPECT_TRUE(result.find("2024") != std::string::npos);
        EXPECT_TRUE(result.find("-") != std::string::npos);
        EXPECT_TRUE(result.find(":") != std::string::npos);
    }

    // 测试仅日期模式
    {
        std::string result = NFTimeUtility::DateTimeToStr(m_testTimestamp, true);
        // 仅日期模式应该只包含时分秒
        EXPECT_TRUE(result.find(":") != std::string::npos);
        EXPECT_EQ(result.length(), 8); // HH:MM:SS格式长度为8
    }
}

/**
 * @brief 测试字符串解析为时间戳功能
 *
 * 测试StrToTime、DateStrToLocalTime等字符串解析函数
 */
TEST_F(NFTimeUtilityTest, StringParseTest)
{
    // 测试StrToTime - 标准日期时间字符串解析
    {
        time_t result = NFTimeUtility::StrToTime("2024-01-15 10:30:45");
        EXPECT_GT(result, 0);

        // 验证解析结果的正确性 - 重新格式化应该得到相同字符串
        std::string formatted = NFTimeUtility::DateTimeToStr(result);
        EXPECT_EQ(formatted, "2024-01-15 10:30:45");
    }

    // 测试错误格式的字符串
    {
        time_t result = NFTimeUtility::StrToTime("invalid-format");
        EXPECT_EQ(result, 0); // 错误格式应该返回0
    }

    // 测试DateStrToLocalTime函数
    {
        time_t result;
        int ret = NFTimeUtility::DateStrToLocalTime("2024-01-15 10:30:45", &result);
        EXPECT_EQ(ret, 0); // 成功返回0
        EXPECT_GT(result, 0);
    }

    // 测试仅日期的解析
    {
        time_t result;
        int ret = NFTimeUtility::DateStrToLocalTime("2024-01-15", &result);
        EXPECT_EQ(ret, 0); // 成功返回0
        EXPECT_GT(result, 0);
    }

    // 测试空指针情况
    {
        int ret = NFTimeUtility::DateStrToLocalTime(nullptr, nullptr);
        EXPECT_EQ(ret, -1); // 空指针应该返回错误
    }
}

/**
 * @brief 测试MakeTime函数
 *
 * 测试通过年月日时分秒参数创建时间戳
 */
TEST_F(NFTimeUtilityTest, MakeTimeTest)
{
    // 测试MakeTime(年,月,日,时,分,秒)
    {
        time_t result = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        EXPECT_GT(result, 0);

        // 验证结果的正确性
        std::string formatted = NFTimeUtility::DateTimeToStr(result);
        EXPECT_EQ(formatted, "2024-01-15 10:30:45");
    }

    // 测试闰年
    {
        time_t result = NFTimeUtility::MakeTime(2024, 2, 29, 12, 0, 0); // 2024是闰年
        EXPECT_GT(result, 0);
    }
}

// ========== 日期时间计算功能测试 ==========

/**
 * @brief 测试获取当前日期信息
 *
 * 测试GetCurDate、GetCurTime等获取日期时间信息的函数
 */
TEST_F(NFTimeUtilityTest, DateTimeInfoTest)
{
    // 测试GetCurDate - 获取年月日信息
    {
        int year, month, monthDay;
        int ret = NFTimeUtility::GetCurDate(m_testTimestamp, year, month, monthDay);
        EXPECT_EQ(ret, 0); // 成功返回0
        EXPECT_EQ(year, 2024);
        EXPECT_EQ(month, 1);
        EXPECT_EQ(monthDay, 15);
    }

    // 测试GetCurTime - 获取星期几和时分秒信息
    {
        int week, hour, minute, second;
        int ret = NFTimeUtility::GetCurTime(m_testTimestamp, week, hour, minute, second);
        EXPECT_EQ(ret, 0); // 成功返回0
        EXPECT_GE(week, 1);
        EXPECT_LE(week, 7);
        EXPECT_GE(hour, 0);
        EXPECT_LE(hour, 23);
        EXPECT_GE(minute, 0);
        EXPECT_LE(minute, 59);
        EXPECT_GE(second, 0);
        EXPECT_LE(second, 59);
    }

    // 测试获取小时和分钟
    {
        int hour = NFTimeUtility::GetCurHour(m_testTimestamp);
        EXPECT_GE(hour, 0);
        EXPECT_LE(hour, 23);

        int minute = NFTimeUtility::GetCurMin(m_testTimestamp);
        EXPECT_GE(minute, 0);
        EXPECT_LE(minute, 59);
    }
}

/**
 * @brief 测试星期相关功能
 *
 * 测试GetWeekDay、GetWeekDay127等星期相关函数
 */
TEST_F(NFTimeUtilityTest, WeekDayTest)
{
    // 测试GetWeekDay (0-6格式，0=星期日)
    {
        int weekDay = NFTimeUtility::GetWeekDay(m_testTimestamp);
        EXPECT_GE(weekDay, 0);
        EXPECT_LE(weekDay, 6);
    }

    // 测试GetWeekDay127 (1-7格式，1=星期一)
    {
        int weekDay = NFTimeUtility::GetWeekDay127(m_testTimestamp);
        EXPECT_GE(weekDay, 1);
        EXPECT_LE(weekDay, 7);
    }
}

/**
 * @brief 测试月份相关功能
 *
 * 测试GetMonthDay、GetCurMonthDay等月份相关函数
 */
TEST_F(NFTimeUtilityTest, MonthTest)
{
    // 测试GetMonthDay
    {
        int monthDay = NFTimeUtility::GetMonthDay(m_testTimestamp);
        EXPECT_GE(monthDay, 1);
        EXPECT_LE(monthDay, 31);
    }

    // 测试GetCurMonthDay - 获取指定年月的天数
    {
        // 测试普通月份
        short days = NFTimeUtility::GetCurMonthDay(2024, 1); // 一月
        EXPECT_EQ(days, 31);

        days = NFTimeUtility::GetCurMonthDay(2024, 4); // 四月
        EXPECT_EQ(days, 30);

        // 测试闰年二月
        days = NFTimeUtility::GetCurMonthDay(2024, 2); // 2024是闰年
        EXPECT_EQ(days, 29);

        // 测试非闰年二月
        days = NFTimeUtility::GetCurMonthDay(2023, 2); // 2023不是闰年
        EXPECT_EQ(days, 28);

        // 测试无效月份
        days = NFTimeUtility::GetCurMonthDay(2024, 13);
        EXPECT_EQ(days, 0);
    }

    // 测试IsLeapYear
    {
        EXPECT_TRUE(NFTimeUtility::IsLeapYear(2024)); // 能被4整除
        EXPECT_FALSE(NFTimeUtility::IsLeapYear(2023)); // 不能被4整除
        EXPECT_FALSE(NFTimeUtility::IsLeapYear(1900)); // 能被100整除但不能被400整除
        EXPECT_TRUE(NFTimeUtility::IsLeapYear(2000)); // 能被400整除
    }
}

// ========== 时间比较和周期判断测试 ==========

/**
 * @brief 测试同一时间段判断功能
 *
 * 测试IsSameDay、IsSameWeek、IsSameMonth等时间段判断函数
 */
TEST_F(NFTimeUtilityTest, SamePeriodTest)
{
    // 创建测试用的时间戳
    time_t time1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45); // 2024-01-15 10:30:45
    time_t time2 = NFTimeUtility::MakeTime(2024, 1, 15, 14, 20, 30); // 同一天的不同时间
    time_t time3 = NFTimeUtility::MakeTime(2024, 1, 16, 8, 15, 20); // 不同天
    time_t time4 = NFTimeUtility::MakeTime(2024, 2, 15, 10, 30, 45); // 不同月
    time_t time5 = NFTimeUtility::MakeTime(2024, 1, 15, 03, 30, 45); // 2024-01-15 10:30:45

    // 测试IsSameDay
    {
        EXPECT_TRUE(NFTimeUtility::IsSameDay(time1, time2)); // 同一天
        EXPECT_FALSE(NFTimeUtility::IsSameDay(time1, time3)); // 不同天
        EXPECT_FALSE(NFTimeUtility::IsSameDay(time1, time5)); // 不同天

        // 测试IsSameDayCommon
        EXPECT_TRUE(NFTimeUtility::IsSameDayCommon(time1, time2));
        EXPECT_FALSE(NFTimeUtility::IsSameDayCommon(time1, time3));

        // 测试IsSameDayStd
        EXPECT_TRUE(NFTimeUtility::IsSameDayStd(time1, time2, 0));
        EXPECT_FALSE(NFTimeUtility::IsSameDayStd(time1, time3, 0));
    }

    // 测试IsSameHour
    {
        time_t hourTime1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        time_t hourTime2 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 45, 20); // 同一小时
        time_t hourTime3 = NFTimeUtility::MakeTime(2024, 1, 15, 11, 30, 45); // 不同小时

        EXPECT_TRUE(NFTimeUtility::IsSameHour(hourTime1, hourTime2));
        EXPECT_FALSE(NFTimeUtility::IsSameHour(hourTime1, hourTime3));
    }

    // 测试IsSameMonth
    {
        EXPECT_TRUE(NFTimeUtility::IsSameMonth(time1, time2)); // 同一月
        EXPECT_TRUE(NFTimeUtility::IsSameMonth(time1, time3)); // 同一月不同天
        EXPECT_FALSE(NFTimeUtility::IsSameMonth(time1, time4)); // 不同月

        // 测试IsSameMonthStd
        EXPECT_TRUE(NFTimeUtility::IsSameMonthStd(time1, time2, 0));
        EXPECT_FALSE(NFTimeUtility::IsSameMonthStd(time1, time4, 0));
    }

    // 测试IsSameYear
    {
        time_t yearTime1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        time_t yearTime2 = NFTimeUtility::MakeTime(2024, 12, 31, 23, 59, 59); // 同一年
        time_t yearTime3 = NFTimeUtility::MakeTime(2025, 1, 1, 0, 0, 1); // 不同年

        EXPECT_TRUE(NFTimeUtility::IsSameYear(yearTime1, yearTime2));
        EXPECT_FALSE(NFTimeUtility::IsSameYear(yearTime1, yearTime3));

        // 测试IsSameYearStd
        EXPECT_TRUE(NFTimeUtility::IsSameYearStd(yearTime1, yearTime2, 0));
        EXPECT_FALSE(NFTimeUtility::IsSameYearStd(yearTime1, yearTime3, 0));
    }
}

/**
 * @brief 测试时间间隔判断功能
 *
 * 测试IsTimePassedS、IsTimePassedMs等时间间隔判断函数
 */
TEST_F(NFTimeUtilityTest, TimeIntervalTest)
{
    // 测试IsTimePassedS - 秒级时间间隔判断
    {
        time_t now = time(nullptr);
        time_t past = now - 10; // 10秒前

        EXPECT_TRUE(NFTimeUtility::IsTimePassedS(now, past, 5)); // 超过5秒
        EXPECT_FALSE(NFTimeUtility::IsTimePassedS(now, past, 15)); // 未超过15秒
        EXPECT_TRUE(NFTimeUtility::IsTimePassedS(now, past, 10)); // 正好10秒
    }

    // 测试IsTimePassedMs - 毫秒级时间间隔判断
    {
        struct timeval tv1, tv2;
        gettimeofday(&tv1, nullptr);

        // 模拟100毫秒前的时间
        tv2 = tv1;
        tv2.tv_usec -= 100000; // 减少100000微秒（100毫秒）
        if (tv2.tv_usec < 0)
        {
            tv2.tv_usec += 1000000;
            tv2.tv_sec -= 1;
        }

        EXPECT_TRUE(NFTimeUtility::IsTimePassedMs(tv1, tv2, 50)); // 超过50毫秒
        EXPECT_FALSE(NFTimeUtility::IsTimePassedMs(tv1, tv2, 150)); // 未超过150毫秒
    }
}

// ========== 时间计算功能测试 ==========

/**
 * @brief 测试时间起始和结束点计算
 *
 * 测试GetTodayStartTime、GetWeekStartTime、GetMonthStartTime等函数
 */
TEST_F(NFTimeUtilityTest, TimeRangeTest)
{
    // 测试GetTodayStartTime - 获取今天开始时间
    {
        time_t startTime = NFTimeUtility::GetTodayStartTime(m_testTimestamp, 0);
        EXPECT_GT(startTime, 0);
        EXPECT_LE(startTime, m_testTimestamp); // 开始时间应该早于或等于给定时间

        // 验证开始时间是当天的00:00:00
        std::string formatted = NFTimeUtility::DateTimeToStr(startTime);
        EXPECT_TRUE(formatted.find("00:00:00") != std::string::npos);
    }

    // 测试GetTodayEndTime - 获取今天结束时间
    {
        time_t endTime = NFTimeUtility::GetTodayEndTime(m_testTimestamp, 0);
        EXPECT_GT(endTime, 0);
        EXPECT_GT(endTime, m_testTimestamp); // 结束时间应该晚于给定时间
    }

    // 测试GetWeekStartTime - 获取本周开始时间
    {
        time_t weekStart = NFTimeUtility::GetWeekStartTime(m_testTimestamp, 0);
        EXPECT_GT(weekStart, 0);
        EXPECT_LE(weekStart, m_testTimestamp);

        // 验证是星期一
        int weekDay = NFTimeUtility::GetWeekDay127(weekStart);
        EXPECT_EQ(weekDay, 1); // 1表示星期一
    }

    // 测试GetWeekEndTime - 获取本周结束时间
    {
        time_t weekEnd = NFTimeUtility::GetWeekEndTime(m_testTimestamp, 0);
        EXPECT_GT(weekEnd, 0);
        EXPECT_GT(weekEnd, m_testTimestamp);
    }

    // 测试GetMonthStartTime - 获取本月开始时间
    {
        time_t monthStart = NFTimeUtility::GetMonthStartTime(m_testTimestamp, 0);
        EXPECT_GT(monthStart, 0);
        EXPECT_LE(monthStart, m_testTimestamp);

        // 验证是月初第一天
        int monthDay = NFTimeUtility::GetMonthDay(monthStart);
        EXPECT_EQ(monthDay, 1);
    }

    // 测试GetMonthEndTime - 获取本月结束时间
    {
        time_t monthEnd = NFTimeUtility::GetMonthEndTime(m_testTimestamp, 0);
        EXPECT_GT(monthEnd, 0);
        EXPECT_GT(monthEnd, m_testTimestamp);
    }
}

/**
 * @brief 测试时间差计算功能
 *
 * 测试GetDayElapse、GetOffsetWeeks等时间差计算函数
 */
TEST_F(NFTimeUtilityTest, TimeDifferenceTest)
{
    // 测试GetDayElapse - 计算天数差
    {
        time_t time1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        time_t time2 = NFTimeUtility::MakeTime(2024, 1, 18, 14, 20, 30); // 3天后

        int dayElapse = NFTimeUtility::GetDayElapse(time2, time1, 0);
        EXPECT_EQ(dayElapse, 3);

        // 反向计算应该返回0（因为time1 < time2）
        int reverseElapse = NFTimeUtility::GetDayElapse(time1, time2, 0);
        EXPECT_EQ(reverseElapse, 0);
    }

    // 测试GetDaysDelta - 计算天数差（可以为负数）
    {
        time_t time1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        time_t time2 = NFTimeUtility::MakeTime(2024, 1, 18, 14, 20, 30); // 3天后

        int delta = NFTimeUtility::GetDaysDelta(time2, time1);
        EXPECT_EQ(delta, 3);

        int reverseDelta = NFTimeUtility::GetDaysDelta(time1, time2);
        EXPECT_EQ(reverseDelta, -3);
    }

    // 测试GetOffsetWeeks - 计算周数差
    {
        time_t time1 = NFTimeUtility::MakeTime(2024, 1, 8, 10, 30, 45); // 2024年第2周的某天
        time_t time2 = NFTimeUtility::MakeTime(2024, 1, 22, 14, 20, 30); // 2024年第4周的某天

        int weekOffset = NFTimeUtility::GetOffsetWeeks(time1, time2);
        EXPECT_GE(weekOffset, 0); // 应该是正数
    }

    // 测试GetElapseMonths - 计算月数差
    {
        uint32_t time1 = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        uint32_t time2 = NFTimeUtility::MakeTime(2024, 4, 15, 10, 30, 45); // 3个月后

        int monthElapse = NFTimeUtility::GetElapseMonths(time2, time1);
        EXPECT_EQ(monthElapse, 3);

        // 反向计算应该返回-3
        int reverseElapse = NFTimeUtility::GetElapseMonths(time1, time2);
        EXPECT_EQ(reverseElapse, -3);
    }
}

// ========== 特殊功能测试 ==========

/**
 * @brief 测试时间偏移功能
 *
 * 测试GetOffsetToNextHour、GetOffsetToNextDay等偏移计算函数
 */
TEST_F(NFTimeUtilityTest, TimeOffsetTest)
{
    // 测试GetOffsetToNextHour - 到下一个整点的秒数
    {
        time_t testTime = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45); // 10:30:45
        int offset = NFTimeUtility::GetOffsetToNextHour(testTime);
        EXPECT_EQ(offset, 1755); // 到11:00:00还有29分15秒 = 29*60+15 = 1755秒
    }

    // 测试GetOffsetToNextHalfHour - 到下一个半点的秒数
    {
        time_t testTime = NFTimeUtility::MakeTime(2024, 1, 15, 10, 20, 45); // 10:20:45
        int offset = NFTimeUtility::GetOffsetToNextHalfHour(testTime);
        EXPECT_EQ(offset, 555); // 到10:30:00还有9分15秒 = 9*60+15 = 555秒
    }

    // 测试GetOffsetToNextDay - 到下一天的秒数
    {
        time_t testTime = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45);
        int offset = NFTimeUtility::GetOffsetToNextDay(testTime);
        EXPECT_GT(offset, 0);
        EXPECT_LT(offset, 86400); // 小于一天的秒数
    }
}

/**
 * @brief 测试游戏相关的时间功能
 *
 * 测试游戏开服时间、星期控制等游戏特定功能
 */
TEST_F(NFTimeUtilityTest, GameSpecificTest)
{
    // 测试GetOpenDayWeekInfo - 开服天数对应的周数和星期
    {
        uint32_t serverOpenTime = NFTimeUtility::MakeTime(2024, 1, 15, 0, 0, 0); // 假设周一开服
        int openWeek, weekDay;

        // 测试开服第1天
        NFTimeUtility::GetOpenDayWeekInfo(serverOpenTime, 1, openWeek, weekDay);
        EXPECT_EQ(openWeek, 1);
        EXPECT_GE(weekDay, 1);
        EXPECT_LE(weekDay, 7);

        // 测试开服第8天（应该是第2周）
        NFTimeUtility::GetOpenDayWeekInfo(serverOpenTime, 8, openWeek, weekDay);
        EXPECT_EQ(openWeek, 2);
    }

    // 测试IsOkWithWeekDayCtrl - 星期控制功能
    {
        uint32_t testTime = NFTimeUtility::MakeTime(2024, 1, 15, 10, 30, 45); // 获取这天是星期几
        int weekDay = NFTimeUtility::GetWeekDay127(testTime);

        // 创建只允许该星期的控制标志
        uint8_t allowFlag = (1 << (weekDay - 1));
        EXPECT_TRUE(NFTimeUtility::IsOkWithWeekDayCtrl(allowFlag, testTime));

        // 创建不允许该星期的控制标志
        uint8_t disallowFlag = 0x7F ^ allowFlag; // 除了该星期都允许
        EXPECT_FALSE(NFTimeUtility::IsOkWithWeekDayCtrl(disallowFlag, testTime));
    }

    // 测试GetWeekCycleChainIndex - 周循环链索引
    {
        int chainIndex = NFTimeUtility::GetWeekCycleChainIndex(m_testTimestamp, 4);
        EXPECT_GE(chainIndex, 1);
        EXPECT_LE(chainIndex, 4);
    }
}

/**
 * @brief 测试CalcAndCheckTime功能
 *
 * 测试时间字符串的解析和验证功能
 */
TEST_F(NFTimeUtilityTest, CalcAndCheckTimeTest)
{
    NFTimeUtility timeUtil;

    // 测试有效的时间字符串
    {
        uint32_t timestamp;
        int ret = timeUtil.CalcAndCheckTime("2024-01-15 10:30:45", timestamp);
        EXPECT_EQ(ret, 0);
        EXPECT_GT(timestamp, 0);
    }

    // 测试空字符串（视为未配置）
    {
        uint32_t timestamp;
        int ret = timeUtil.CalcAndCheckTime("", timestamp);
        EXPECT_EQ(ret, 0);
        EXPECT_EQ(timestamp, 0);
    }

    // 测试长度错误的字符串
    {
        uint32_t timestamp;
        int ret = timeUtil.CalcAndCheckTime("2024-01-15", timestamp);
        EXPECT_EQ(ret, -1);
    }

    // 测试格式错误的字符串
    {
        uint32_t timestamp;
        int ret = timeUtil.CalcAndCheckTime("invalid-time-format", timestamp);
        EXPECT_EQ(ret, -1);
    }
}

// ========== 时间值操作测试 ==========

/**
 * @brief 测试NFTimeVal相关操作
 *
 * 测试AddMs、AddUs、TimeMsPass等微秒精度时间操作
 */
TEST_F(NFTimeUtilityTest, TimeValOperationTest)
{
    // 测试AddMs - 添加毫秒
    {
        NFTimeVal tv = {1000, 500000}; // 1000秒 + 500000微秒（0.5秒）
        NFTimeUtility::AddMs(tv, 1500); // 添加1500毫秒（1.5秒）

        EXPECT_EQ(tv.tv_sec, 1002); // 1000 + 1.5 + 0.5 = 1002秒
        EXPECT_EQ(tv.tv_usec, 0); // 微秒部分应该为0
    }

    // 测试AddUs - 添加微秒
    {
        NFTimeVal tv = {1000, 500000}; // 1000秒 + 500000微秒
        NFTimeUtility::AddUs(tv, 600000); // 添加600000微秒（0.6秒）

        EXPECT_EQ(tv.tv_sec, 1001); // 1000 + 1 = 1001秒
        EXPECT_EQ(tv.tv_usec, 100000); // 500000 + 600000 - 1000000 = 100000微秒
    }

    // 测试SecondTimeToStr - 时间值转字符串
    {
        NFTimeVal tv = {1234567890, 123456};
        std::string result = NFTimeUtility::SecondTimeToStr(tv);
        EXPECT_EQ(result, "1234567890:123456");
    }

    // 测试时间值比较操作符
    {
        NFTimeVal tv1 = {1000, 500000};
        NFTimeVal tv2 = {1000, 600000};
        NFTimeVal tv3 = {1001, 0};

        EXPECT_TRUE(tv1 < tv2); // 同秒数，微秒数小
        EXPECT_TRUE(tv1 < tv3); // 秒数小
        EXPECT_TRUE(tv1 <= tv2);
        EXPECT_FALSE(tv1 == tv2);

        NFTimeVal tv4 = tv1;
        EXPECT_TRUE(tv1 == tv4);
        EXPECT_TRUE(tv1 <= tv4);
    }

    // 测试时间值减法操作
    {
        NFTimeVal tv1 = {1001, 100000};
        NFTimeVal tv2 = {1000, 600000};
        NFTimeVal result = tv1 - tv2;

        EXPECT_EQ(result.tv_sec, 0);
        EXPECT_EQ(result.tv_usec, 500000); // 1.1秒 - 1.6秒 = 0.5秒
    }
}

// ========== 边界条件和异常测试 ==========

/**
 * @brief 测试边界条件和异常情况
 *
 * 测试各种边界值和错误输入的处理
 */
TEST_F(NFTimeUtilityTest, BoundaryAndErrorTest)
{
    // 测试时间戳为0的情况
    {
        std::string result = NFTimeUtility::DateTimeToStr(0);
        EXPECT_FALSE(result.empty());
    }

    // 测试超大时间戳的情况（接近2038年问题）
    {
        time_t maxTime = 2147483647; // 2038-01-19 03:14:07 UTC
        std::string result = NFTimeUtility::DateTimeToStr(maxTime);
        EXPECT_FALSE(result.empty());
    }

    // 测试无效月份天数
    {
        short days = NFTimeUtility::GetCurMonthDay(2024, 0); // 无效月份
        EXPECT_EQ(days, 0);

        days = NFTimeUtility::GetCurMonthDay(2024, 13); // 无效月份
        EXPECT_EQ(days, 0);
    }

    // 测试GetTimeSec的错误输入
    {
        time_t result;
        int ret = NFTimeUtility::GetTimeSec("25:00:00", &result); // 无效小时
        EXPECT_EQ(ret, 0);

        ret = NFTimeUtility::GetTimeSec("10:60:00", &result); // 无效分钟
        EXPECT_EQ(ret, 0);

        ret = NFTimeUtility::GetTimeSec("10:30:60", &result); // 无效秒数
        EXPECT_EQ(ret, 0);
    }

    // 测试空指针输入
    {
        time_t result;
        int ret = NFTimeUtility::GetTimeSec(nullptr, &result);
        EXPECT_EQ(ret, -1);

        ret = NFTimeUtility::GetTimeSec("10:30:45", nullptr);
        EXPECT_EQ(ret, -1);
    }
}

/**
 * @brief 测试时区相关功能
 *
 * 测试时区偏移和本地时间转换功能
 */
TEST_F(NFTimeUtilityTest, TimeZoneTest)
{
    // 测试GetCurTimeZone - 获取当前时区
    {
        int32_t timeZone = NFTimeUtility::GetCurTimeZone();
        EXPECT_GE(timeZone, -12); // 时区范围通常在-12到+14之间
        EXPECT_LE(timeZone, 14);
    }

    // 测试GetGmtSec - 获取GMT偏移秒数
    {
        uint32_t gmtSec = NFTimeUtility::GetGmtSec();
        // GMT偏移秒数应该在合理范围内
        EXPECT_LE(gmtSec, 50400); // 最大14小时的偏移
    }

#ifdef I18N_GLOBAL
    // 测试时区偏移设置和获取（仅在I18N_GLOBAL宏定义时可用）
    {
        int originalOffset = NFTimeUtility::GetTimeZoneOffset();

        NFTimeUtility::SetTimeZoneOffset(8); // 设置为GMT+8
        EXPECT_EQ(NFTimeUtility::GetTimeZoneOffset(), 8);

        NFTimeUtility::SetTimeZoneOffset(-5); // 设置为GMT-5
        EXPECT_EQ(NFTimeUtility::GetTimeZoneOffset(), -5);

        // 恢复原始偏移
        NFTimeUtility::SetTimeZoneOffset(originalOffset);
    }
#endif
}

/**
 * @brief 测试绝对时间计算功能
 *
 * 测试GetAbsDay、GetAbsWeek等绝对时间计算函数
 */
TEST_F(NFTimeUtilityTest, AbsoluteTimeTest)
{
    // 测试GetAbsDay - 获取绝对天数
    {
        uint32_t absDay = NFTimeUtility::GetAbsDay(m_testTimestamp, 0);
        EXPECT_GT(absDay, 0);

        // 测试带小时偏移的绝对天数
        uint32_t absDayWithOffset = NFTimeUtility::GetAbsDay(m_testTimestamp, 4);
        // 带偏移的绝对天数可能与不带偏移的不同
    }

    // 测试GetAbsWeek - 获取绝对周数
    {
        uint32_t absWeek = NFTimeUtility::GetAbsWeek(m_testTimestamp);
        EXPECT_GT(absWeek, 0);

        // 测试早于基准时间的情况
        uint32_t earlyWeek = NFTimeUtility::GetAbsWeek(100); // 很早的时间戳
        EXPECT_EQ(earlyWeek, 0); // 应该返回0
    }

    // 测试GetDayAbsSec - 获取一天中的绝对秒数
    {
        uint32_t absSec = NFTimeUtility::GetDayAbsSec(m_testTimestamp);
        EXPECT_GE(absSec, 0);
        EXPECT_LT(absSec, 86400); // 小于一天的秒数
    }

    // 测试GetAbsTimeByWeekDayAndTime - 根据星期几和时间偏移计算绝对时间
    {
        uint32_t absTime = NFTimeUtility::GetAbsTimeByWeekDayAndTime(m_testTimestamp, 3, 3600 * 10); // 周三上午10点
        EXPECT_GT(absTime, 0);

        // 验证计算结果的星期几
        int weekDay = NFTimeUtility::GetWeekDay127(absTime);
        EXPECT_EQ(weekDay, 3); // 应该是周三
    }
}

/**
 * @brief 性能测试
 *
 * 测试关键函数的性能表现
 */
TEST_F(NFTimeUtilityTest, PerformanceTest)
{
    const int iterations = 10000;
    time_t testTime = m_testTimestamp;

    // 测试DateTimeToStr的性能
    {
        auto start = std::chrono::high_resolution_clock::now();

        for (int i = 0; i < iterations; ++i)
        {
            std::string result = NFTimeUtility::DateTimeToStr(testTime + i);
        }

        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

        // 性能测试不做严格断言，只是确保能正常执行
        EXPECT_LT(duration.count(), 5000); // 应该在5秒内完成
    }

    // 测试GetWeekDay127的性能
    {
        auto start = std::chrono::high_resolution_clock::now();

        for (int i = 0; i < iterations; ++i)
        {
            int weekDay = NFTimeUtility::GetWeekDay127(testTime + i * 86400);
            EXPECT_GE(weekDay, 1);
            EXPECT_LE(weekDay, 7);
        }

        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

        EXPECT_LT(duration.count(), 1000); // 应该在1秒内完成
    }
}
